/*
 * Copyright (C) 2010 Tetsuya Yasuda <tetsuyayasuda@gmail.com>
 */
package jp.tyas.libs.lisp;

public class Symbol
{
    String name;
    Object value;
    Callee callee;
    boolean resolved;

    public Symbol (String name)
    {
        this.name = name;
        this.resolved = false;
    }
    
    public Symbol (String name, Object value, Callee callee)
    {
        this.name = name;
        this.value = value;
        this.callee = callee;
        this.resolved = true;
    }

    public Symbol resolve(Context ctx)
    {
        return resolved ? this : ctx.find (name);
    }

    public String toString ()
    {
        return name;
    }

    public String getName ()
    {
        return name;
    }

    public Object getValue ()
    {
        if (!resolved)
            throw new LispError ("getValue(): Symbol Unresolved");
        return value;
    }

    public void setValue (Object sexp)
    {
        if (!resolved)
            throw new LispError ("setValue(): Symbol Unresolved");
        
        value = sexp;
    }

    public Callee getCallee ()
    {
        if (!resolved)
            throw new LispError ("getCallee(): Symbol Unresolved");

        return callee;
    }

    public void setCallee (Callee c)
    {
        if (!resolved)
            throw new LispError ("setCallee(): Symbol Unresolved");
        
        callee = c;
    }

    public boolean equals (Object obj)
    {
        Symbol ano = (Symbol) obj;

        if (!resolved && !ano.resolved)
            return name.equals (ano.name);

        return this == obj;
    }
}
